
#include "Stats_ServerOptions.hpp"

bool Stats_ServerOptions::Parse(std::string const& ConfigName,int argc,char *argv[],boost::shared_ptr<ValueTypeMap> pVM)
{

        boost::program_options::options_description description("Stats_Server options");
        endpoint  net_mgroup;
        endpoint  net_local_if;
        int  net_ttl;
        int  net_flight_base;
        int  net_flight_incr;
        int  net_nitems;
        std::string  net_cluster;
        std::string  net_node;
        std::string  encrypt_iv;
        std::string  encrypt_key;
        std::string  persist_path;
        int  persist_interval;
        int  persist_age;
        std::string  log_path;
        int  system_threads;
        ;
        description.add_options()
        ("help", "help message")
        ("debug","debug run")
        ("net.mgroup",boost::program_options::value< endpoint >(&net_mgroup) ->required(),"net mgroup: ip_port (ex:239.44.12.23:2447)")
        ("net.local_if",boost::program_options::value< endpoint >(&net_local_if) ,"net local_if: ip_port (ex:0.0.0.0:0 )")
        ("net.ttl",boost::program_options::value< int >(&net_ttl) ->default_value(1),"net ttl: int (ex:1 )")
        ("net.flight_base",boost::program_options::value< int >(&net_flight_base) ->default_value(300),"net flight_base: int (ex:300 )")
        ("net.flight_incr",boost::program_options::value< int >(&net_flight_incr) ->default_value(30),"net flight_incr: int (ex:30  )")
        ("net.nitems",boost::program_options::value< int >(&net_nitems) ->default_value(10),"net nitems: int (ex:10  )")
        ("net.cluster",boost::program_options::value< std::string >(&net_cluster) ->required(),"net cluster: string (ex:cluster1)")
        ("net.node",boost::program_options::value< std::string >(&net_node) ->required(),"net node: string (ex:node1)")
        ("encrypt.iv",boost::program_options::value< std::string >(&encrypt_iv) ->required(),"encrypt iv: string (ex:52CBAB9E3004BF42642C8AC0871B4DF9)")
        ("encrypt.key",boost::program_options::value< std::string >(&encrypt_key) ->required(),"encrypt key: string (ex:D9007ED97246FCC5AC65F7D2FFEE22B9)")
        ("persist.path",boost::program_options::value< std::string >(&persist_path) ->required(),"persist path: string (ex:cluster_statistics.pb)")
        ("persist.interval",boost::program_options::value< int >(&persist_interval) ->default_value(20),"persist interval: int (ex:20 )")
        ("persist.age",boost::program_options::value< int >(&persist_age) ->default_value(10),"persist age: int (ex:500 )")
        ("log.path",boost::program_options::value< std::string >(&log_path) ->required(),"log path: string (ex:logs)")
        ("system.threads",boost::program_options::value< int >(&system_threads) ->default_value(3),"system threads: int (ex:3 )")
        ;
        boost::program_options::variables_map vars_map;
        boost::program_options::store(boost::program_options::parse_command_line(argc,argv,description),vars_map);
        if(vars_map.count("help"))std::cout<<description<<std::endl;
        if(vars_map.count("debug"))std::cout<<"debug mode"<<std::endl;
        //if config is a usefull parameter in ctor, then use it, else ignore it
        if(ConfigName.size())
        {
            std::ifstream conf(ConfigName.c_str());
            if(conf.is_open())
                boost::program_options::store(boost::program_options::parse_config_file(conf,description),vars_map);
            else
                throw std::runtime_error(ConfigName+":"+std::strerror( errno ));
            //override config with command line
            boost::program_options::store(boost::program_options::parse_command_line(argc,argv,description),vars_map);
        }
        boost::program_options::notify(vars_map);
        if(vars_map["net.mgroup"].defaulted()||vars_map.count("net.mgroup"))pVM->insert(std::make_pair("net.mgroup", ValueType(net_mgroup)));
        if(vars_map["net.local_if"].defaulted()||vars_map.count("net.local_if"))pVM->insert(std::make_pair("net.local_if", ValueType(net_local_if)));
        if(vars_map["net.ttl"].defaulted()||vars_map.count("net.ttl"))pVM->insert(std::make_pair("net.ttl", ValueType(net_ttl)));
        if(vars_map["net.flight_base"].defaulted()||vars_map.count("net.flight_base"))pVM->insert(std::make_pair("net.flight_base", ValueType(net_flight_base)));
        if(vars_map["net.flight_incr"].defaulted()||vars_map.count("net.flight_incr"))pVM->insert(std::make_pair("net.flight_incr", ValueType(net_flight_incr)));
        if(vars_map["net.nitems"].defaulted()||vars_map.count("net.nitems"))pVM->insert(std::make_pair("net.nitems", ValueType(net_nitems)));
        if(vars_map["net.cluster"].defaulted()||vars_map.count("net.cluster"))pVM->insert(std::make_pair("net.cluster", ValueType(net_cluster)));
        if(vars_map["net.node"].defaulted()||vars_map.count("net.node"))pVM->insert(std::make_pair("net.node", ValueType(net_node)));
        if(vars_map["encrypt.iv"].defaulted()||vars_map.count("encrypt.iv"))pVM->insert(std::make_pair("encrypt.iv", ValueType(encrypt_iv)));
        if(vars_map["encrypt.key"].defaulted()||vars_map.count("encrypt.key"))pVM->insert(std::make_pair("encrypt.key", ValueType(encrypt_key)));
        if(vars_map["persist.path"].defaulted()||vars_map.count("persist.path"))pVM->insert(std::make_pair("persist.path", ValueType(persist_path)));
        if(vars_map["persist.interval"].defaulted()||vars_map.count("persist.interval"))pVM->insert(std::make_pair("persist.interval", ValueType(persist_interval)));
        if(vars_map["persist.age"].defaulted()||vars_map.count("persist.age"))pVM->insert(std::make_pair("persist.age", ValueType(persist_age)));
        if(vars_map["log.path"].defaulted()||vars_map.count("log.path"))pVM->insert(std::make_pair("log.path", ValueType(log_path)));
        if(vars_map["system.threads"].defaulted()||vars_map.count("system.threads"))pVM->insert(std::make_pair("system.threads", ValueType(system_threads)));
        if(vars_map.count("debug"))pVM->insert(std::make_pair("debug",ValueType(1)));
        else pVM->insert(std::make_pair("debug",ValueType(0)));
        if(vars_map.count("help"))pVM->insert(std::make_pair("help",ValueType(1)));
        else pVM->insert(std::make_pair("help",ValueType(0)));
        return true;
}
